<?php

namespace app\service;

class Lottery
{
    /**
     * 概率基数
     * @var int
     */
    private $total_chance = 10000;

    /**
     * 谢谢参与奖励
     * @var array
     */
    private $thanks_prize = [
        'id' => 0,
        'pid' => 0,
        'type' => 1,
        'name' => '谢谢参与'
    ];

    /**
     * 奖池 TODO: 应用场景从数据库中读出来/加入缓存
     *  id 奖品的id
        pid 奖品的自定义id
        type 奖品类型，1、虚拟奖品 2、实物奖品 3、礼包码 待扩充
        name 奖品名称
        total 奖品总数
        chance 获奖概率/抽奖基数10000
        dayNum 每日数量限制
        pay 充值限制
     * @var array
     */
    private $prize = [
        ['id' => 1, 'pid' => 11, 'type' => 1, 'name' => '典藏英雄', 'total' => 20, 'chance' => 1000, 'dayLimit' => 10, 'pay' => 2000],
        ['id' => 2, 'pid' => 12, 'type' => 1, 'name' => '史诗皮肤', 'total' => 40, 'chance' => 1000, 'dayLimit' => 10, 'pay' => 4000],
        ['id' => 3, 'pid' => 13, 'type' => 1, 'name' => '钻石奖励', 'total' => 80, 'chance' => 1000, 'dayLimit' => 10, 'pay' => 4000],
        ['id' => 4, 'pid' => 14, 'type' => 1, 'name' => '荣耀水晶', 'total' => 20, 'chance' => 1000, 'dayLimit' => 10, 'pay' => 8000]
    ];

    /**
     * Lottery constructor.
     */
    public function __construct()
    {
    }

    private function __clone()
    {
    }

    /**
     * 获取用户充值数据
     * @return int
     */
    private function get_user_pay()
    {
        //TODO: 获取用户正确的充值信息
        return 3000;
    }

    /**
     * 重构奖池、重组概率
     * @return array
     */
    private function init_lottery_pond()
    {
        //过滤控制：初步过滤一些必要因素，比如充值，角色创建时间等充值限制
        $user_pay = $this->get_user_pay();
        foreach ($this->prize as $key => $value) {
            if ($value['pay'] <= $user_pay) unset($this->prize[$key]);
        }

        //初步过滤后，重构新的抽奖信息，加入谢谢参与
        $now_chance = array_sum(array_column($this->prize, 'chance'));
        $remain_chance = $this->total_chance - $now_chance;
        $this->prize[] = ['id' => 0, 'pid' => 0, 'type' => 1, 'name' => '谢谢参与', 'total' => 0, 'chance' => $remain_chance, 'dayLimit' => 0, 'pay' => 0];

        //重组概率
        $num = 0;
        $award = [];
        foreach ($this->prize as $v) {
            $num += $v['chance'];
            $award[] = ['id' => $v['id'], 'pid' => $v['pid'], 'type' => $v['type'], 'name' => $v['name'], 'total' => $v['total'], 'chance' => $num, 'dayLimit' => $v['dayLimit'], 'pay' => $v['pay']];
        }

        return $award;
    }

    /**
     * 获取抽奖结果
     * @return array
     */
    public function get_prize()
    {
        $award = $this->init_lottery_pond();
        $rand = mt_rand(1, $this->total_chance);
        $result = [];
        foreach ($award as $k => $v) {
            $prevChance = $k == 0 ? 0 : $award[$k - 1]['chance'];
            if ($rand > $prevChance && $rand <= $v['chance']) {
                $result = $v;
                break;
            }
        }

        return $this->filter($result);
    }

    /**
     * 抽奖过滤回调函数
     * @param $result
     * @return array
     */
    public function filter($result)
    {
        //奖品总数限制 TODO: 此处应该查数据库
        $yet_num = 30;
        if ($result['pid'] != 0 && $yet_num > $result['total']) {
            $result = $this->thanks_prize;
        }

        //奖品每日数量限制 TODO: 此处应该查数据库
        $yet_today_num = 5;
        if ($result['pid'] != 0 && $yet_today_num > $result['dayLimit']) {
            $result = $this->thanks_prize;
        }

        //不暴露敏感信息
        unset($result['total'], $result['chance'], $result['dayLimit'], $result['pay']);
        return $result;
    }
}